﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using ComputerResourceConsole.lib;
using ComputerResourceConsole.factory;
using ComputerResourceConsole.common;

namespace ComputerResourceConsole.view
{
    public partial class frm_packing : Form
    {
        private string _strWrappingFiler = "python (*.py)|*.py";
        private int _selectedColumnIndex = -1;
        private IPackingControl _pPackingCtrl = null;
        

        public List<string> ModelFiles
        {
            get
            {
                List<string> modelfilelist = new List<string>();
                for (int i = 0; i < this.dgv_files.Rows.Count; i++)
                {
                    modelfilelist.Add(dgv_files.Rows[i].Cells[0].Value.ToString());
                }
                return modelfilelist;
            }
        }

        public frm_packing()
        {
            this._pPackingCtrl = ComponentControlFactory.createPackingControl();
            InitializeComponent();

            //! For test!
            //this.dgv_files.Rows.Add("E:\\GitCode\\ogms\\python\\ogms\\context\\yolov5s.pt");
            //this.dgv_files.Rows.Add("E:\\GitCode\\ogms\\python\\ogms\\context\\yolov5\\");
        }

        public string ProgrammingLanguage
        {
            get
            {
                if (rb_programming_python.Checked)
                {
                    return "Python";
                }
                else if (rb_programming_cs.Checked)
                {
                    return "CSharp";
                }
                return "";
            }
        }

        public string License
        {
            get
            {
                if (rb_license_MIT.Checked)
                {
                    return "MIT";
                }
                else if (rb_license_apache.Checked)
                {
                    return "Apache";
                }
                else if (rb_license_gpl.Checked)
                {
                    return "GPL";
                }
                return "";
            }
        }

        private void bt_pickWrappingFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = this._strWrappingFiler;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.tb_wrappingfilepath.Text = ofd.FileName;
            }
        }

        private void bt_pickMDLFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "MDL file (*.mdl)|*.mdl";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.tb_mdlpath.Text = ofd.FileName;
            }
        }

        private void bt_packing_Click(object sender, EventArgs e)
        {
            //! Checking
            if (this.tb_modelName.Text == "")
            {
                MessageBox.Show("Please fill model name!", "Warning");
                return;
            }
            if (this.tb_author.Text == "")
            {
                MessageBox.Show("Please fill model author!", "Warning");
                return;
            }
            if (this.tb_wrappingfilepath.Text == "")
            {
                MessageBox.Show("Please select wrapping file!", "Warning");
                return;
            }
            if (this.tb_mdlpath.Text == "")
            {
                MessageBox.Show("Please select MDL file!", "Warning");
                return;
            }
            if (this.tb_savepath.Text == "")
            {
                MessageBox.Show("Please select saving path!", "Warning");
                return;
            }
            if (!Directory.Exists(this.tb_savepath.Text))
            {
                MessageBox.Show("Saving path is not existing!", "Warning");
                return;
            }
            this.setStatusText("Packing start...");

            string strConfig = this.tb_savepath.Text + "\\" + this.tb_modelName.Text + ".config";

            FileStream fs = new FileStream(strConfig, FileMode.CreateNew, FileAccess.Write, FileShare.None);
            StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
            sw.Write("modelname||" + this.tb_modelName.Text + "\n");
            sw.Write("author||" + this.tb_author.Text + "\n");
            sw.Write("programming||" + this.ProgrammingLanguage + "\n");
            sw.Write("license||" + this.License + "\n");
            sw.Write("wrappingfile||" + this.tb_wrappingfilepath.Text + "\n");
            sw.Write("mdlfile||" + this.tb_mdlpath.Text + "\n");
            sw.Write("targetpath||" + this.tb_savepath.Text + "\n");
            for (int i = 0; i < this.dgv_files.Rows.Count; i++)
            {
                sw.Write("modelfile||" + this.dgv_files.Rows[i].Cells[0].Value + "\n");
            }
            sw.Flush();
            sw.Close();
            fs.Close();
            fs.Dispose();

            //! Start process

            this._pPackingCtrl.ConfigPath = strConfig;
            this._pPackingCtrl.start(this.onPackingExit);
        }

        private void onPackingExit(object sender, EventArgs e)
        {
            if (this.bt_packing.InvokeRequired)
            {
                CommonMethod.CommonEvent stcb = new CommonMethod.CommonEvent(onPackingExit);
                this.Invoke(stcb, new object[] { sender, e });
            }
            else
            {
                this.setStatusText("Finished!");
            }
        }

        private void bt_close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void frm_packing_Shown(object sender, EventArgs e)
        {
            this.rb_programming_python.Checked = true;
            this.rb_programming_cs.Checked = false;
            this.rb_license_MIT.Checked = true;
        }

        private void setStatusText(string status)
        {
            this.ss_packing.Text = status;
        }

        private void bt_addFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "All file (*.*)|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                if (this.existingFileOrFolder(ofd.FileName))
                {
                    MessageBox.Show("This file has been appended!", "Warning");
                }
                else
                {
                    this.dgv_files.Rows.Add(ofd.FileName);
                }
            }
        }

        private void bt_addFolder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                if (this.existingFileOrFolder(fbd.SelectedPath))
                {
                    MessageBox.Show("This folder has been appended!", "Warning");
                }
                else
                {
                    this.dgv_files.Rows.Add(fbd.SelectedPath);
                }
            }
        }

        private void rb_programming_python_CheckedChanged(object sender, EventArgs e)
        {
            this.tb_wrappingfilepath.Text = "";
            if (this.ProgrammingLanguage == "Python")
            {
                this._strWrappingFiler = "Python (*.py)|*.py";
            }
            else
            {
                this._strWrappingFiler = "Execuable file (*.exe)|*.exe";
            }
        }

        private void dgv_files_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1 && e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                this.cms_delete.Show(this, new Point(e.X + 50, e.Y + 30 * (e.RowIndex + 1) + 210));
                this._selectedColumnIndex = e.ColumnIndex;
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this._selectedColumnIndex != -1)
            {
                this.dgv_files.Rows.RemoveAt(_selectedColumnIndex);
            }
        }

        private bool existingFileOrFolder(string fileorfolder)
        {
            List<string> list = this.ModelFiles;
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i] == fileorfolder)
                {
                    return true;
                }
            }
            return false;
        }

        private void bt_outputpath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                this.tb_savepath.Text = fbd.SelectedPath;
            }
        }
    }
}
